import React, { useState, useEffect, useRef } from 'react';
import { Box, Button, Dialog, Divider, Loading, Message, Tab } from '@alifd/next';
import { observer } from 'mobx-react-lite';
import html2canvas from 'html2canvas';
import styles from './QR.module.scss';
import { t } from '@lingui/macro';
import { useStore } from '@/hooks';

interface QRProps {
  name: string; // 二维码描述文字
  open: boolean; // 打开关闭modal
  onCancel: () => void; // 关闭modal事件
  describe?: string; // 底部文字描述
  modalStyle?: React.CSSProperties; // modal自定义样式
  baseUrl: string; // url链接
  twoUrl: string; // 多个url
  okText?: string; // 自定义确定按钮文字
  cancelText?: string; // 自定义取消按钮文字
  username: string;
}

interface ModalProps {
  username: string;
  name: string;
}

interface UserProps {
  inviteCode: string;
}

interface CommandCodeProps {
  result: string;
}

interface AsyncFuncProps {
  getUser: (username: string) => Promise<UserProps>;
  getURL: (inviteCode: string, key: string, scene: number) => Promise<string>;
  getCommandCode: (scene: number, inviteCode: string, key: string) => Promise<CommandCodeProps>;
}

const tabItems = [
  { key: '1', label: t`包车入口` },
  { key: '2', label: t`总入口` },
  // { key: '3', label: t`小红书` },
];

class CodeUrl {
  private modal: ModalProps;
  private setLoading: (loading: boolean) => void;
  private setUrl: (url: string) => void;
  private setCode: (code: string) => void;
  private setInviteCode: (inviteCode: string) => void;
  private store: AsyncFuncProps;

  constructor(
    modal: ModalProps,
    setLoading: (loading: boolean) => void,
    setUrl: (url: string) => void,
    setCode: (code: string) => void,
    setInviteCode: (inviteCode: string) => void,
    store: AsyncFuncProps,
  ) {
    this.modal = modal;
    this.setLoading = setLoading;
    this.setUrl = setUrl;
    this.setCode = setCode;
    this.setInviteCode = setInviteCode;
    this.store = store;
  }

  async fetch(scene: number, key: string) {
    this.setLoading(true);
    const { getUser, getURL, getCommandCode } = this.store;
    try {
      const { inviteCode } = await getUser(this.modal.username);
      const baseUrl: string = await getURL(inviteCode, key, scene);
      const { result } = await getCommandCode(scene, inviteCode, key);
      this.setCode(result);
      this.setUrl(baseUrl);
      this.setInviteCode(inviteCode);
    } catch (error) {
      console.log('🚀 _ file: index.tsx:45 _ CodeUrl _ error:', error);
      throw error;
    } finally {
      this.setLoading(false);
    }
  }

  static create(
    modal: QRProps,
    setLoading: (loading: boolean) => void,
    setUrl: (url: string) => void,
    setCode: (code: string) => void,
    setInviteCode: (inviteCode: string) => void,
    store: AsyncFuncProps,
  ) {
    return new CodeUrl(modal, setLoading, setUrl, setCode, setInviteCode, store);
  }
}

export default observer(function ({ modal, ...props }: { modal: QRProps }, ...any) {
  const [url, setUrl] = useState('');
  const [code, setCode] = useState('');
  const [inviteCode, setInviteCode] = useState('');
  const [key, setKey] = useState('1');
  const [loading, setLoading] = useState(false);
  const { partnerStore: store } = useStore();
  const divRef = useRef<HTMLDivElement | null>(null);
  const CodeUrlfetcher = CodeUrl.create(modal, setLoading, setUrl, setCode, setInviteCode, store);

  useEffect(() => {
    if (modal.open) {
      (async () => {
        await CodeUrlfetcher.fetch(1000, '1');
      })();
    }
    return () => {
      setKey('1');
    };
  }, [modal]);

  const handleOnChangeTab = async (v: string) => {
    setKey(v);
    switch (v) {
      case '1':
        await CodeUrlfetcher.fetch(1000, v);
        break;
      case '2':
        // 跳转到小程序
        await CodeUrlfetcher.fetch(1001, v);
        break;
      case '3':
        // 跳转到小红书
        await CodeUrlfetcher.fetch(1002, v);
        break;
      default:
        break;
    }
  };

  const cancelHandle = () => {
    modal.onCancel();
  };

  const downloadImage = () => {
    // 使用 html2canvas 将 div 转换为图片，并下载到本地
    setTimeout(() => {
      if (divRef.current) {
        html2canvas(divRef.current, { useCORS: true }).then((canvas) => {
          const link = document.createElement('a');
          link.href = canvas.toDataURL('image/png');
          link.download = `${modal.name}专属二维码.png`;
          link.click();
          modal.onCancel();
        });
      }
    }, 500);
  };

  const handleClickCodeCopy = async () => {
    try {
      await navigator.clipboard.writeText(inviteCode);
      Message.success({ content: t`已复制！` });
    } catch (err) {
      console.error('文本复制失败: ', err);
    }
  };

  return (
    <>
      <Dialog
        v2
        title={`【${modal.name}】专属二维码`}
        visible={modal.open}
        style={{ width: 500, ...modal.modalStyle }}
        onOk={downloadImage}
        okProps={{ children: modal.okText }}
        onClose={cancelHandle}
        cancelProps={{ children: modal.cancelText }}
      >
        <Tab defaultActiveKey="1" activeKey={key} onChange={handleOnChangeTab}>
          {tabItems.map((item) => (
            <Tab.Item key={item.key} title={item.label} />
          ))}
        </Tab>
        <Loading visible={loading} style={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
          <div
            // 使用非空断言运算符 ! 来告诉 TypeScript 你确定 ref 不会为 null
            ref={divRef!}
            id="qrcode-container"
            className={styles.qr_container}
          >
            <div className={styles.qr_content}>
              <img style={{ width: '60%' }} src={url} alt="这是一个二维码" />
              <div style={{ marginTop: 30 }}>{modal.name}</div>
              <div>{modal?.describe || '三地通跨境出行服务平台'}</div>
              {/* 指令代码 */}
              <Divider />
              <Box wrap direction="row" justify="center" align="center">
                {/* <div>{t`指令代码：${code}`}</div> */}
                <div>{t`邀请码：${inviteCode}`}</div>
                <Button text type="primary" style={{ marginLeft: 5 }} onClick={handleClickCodeCopy}>{t`复制`}</Button>
              </Box>
            </div>
          </div>
        </Loading>
      </Dialog>
    </>
  );
});
